<?php
namespace Bundle\FireIceBundle\Cache;

use Bundle\FireIceBundle;

use Bundle\FireIceBundle\FireIceEngine;

/**
 * Класс кэша в файловой системе в виде файлов
 * Используемые параметры в конфиге:
 *  bool    fireice.filecache.autocreate - автосоздание директории
 *  string  fireice.filecache.dir - директория назначение
 *   
 */
class FileCache
{
    /**
     * Объект движка FireIceEngine
     * @var FireIceEngine
     */
    private $_engine;

    /**
     * Папка назначение кэша
     * @var string
     * @remarks 'fireice.filecache.dir'
     */
    private $_targetDirectory;

    /**
     * Разрешено ли создание новых директорий
     * @var boolean
     * @remarks 'fireice.filecache.autocreate'
     */
    private $_autoCreateDirectory = false;

    public function __construct(FireIceEngine $engine)
    {
        $this->_engine = $engine;
       
        // Проверка параметров
        if($engine->hasParameter('fireice.filecache.dir'))
        {
            $this->_targetDirectory = $engine->getParameter('fireice.filecache.dir'); 
        }
        else
        {
            if($engine->hasParameter('kernel.cache_dir'))
            {
                $this->_targetDirectory = $engine->getParameter('kernel.cache_dir') . '\\fireice\\';
            }
            else
            {
                throw new \Exception('No directories are set in `fireice.filecache.dir` or `kernel.cache_dir`');
            }
        }
        
        if($engine->hasParameter('fireice.filecache.autocreate'))
        {
            $this->_autoCreateDirectory = $engine->getParameter('fireice.filecache.autocreate');
        }
        
        $this->_targetDirectory = rtrim($this->_targetDirectory, '\\/');
    }

    /**
     * Получение пути к директории назначению.
     * @return string
     */
    public function getTargetDirectory()
    {
    	return $this->_targetDirectory;
    }
    
    public function contains($filename)
    {
    	return file_exists($this->_targetDirectory . DIRECTORY_SEPARATOR . $filename);
    }
    
    
    /**
     * @throws Exception
     * @param  $filename
     * @param bool $throw Если истина, при ошибке будет создан Exception, иначе возвращено false
     * @return bool|string
     */
    public function fetch($filename, $throw = false)
    {
        if(!is_dir($this->_targetDirectory))
        {
            if($throw)
            {
                throw new \Exception(sprintf('FileCache directory `%s` doesn\'t exist.',
                    $this->_targetDirectory));
            }
            return false;
        }
        $targetFile = realpath($this->_targetDirectory . '\\' . $filename);

        if(!file_exists($targetFile))
        {
            if($throw)
            {
                throw new \Exception(sprintf('FileCache target file `%s` doesn\'t exist.',
                    $targetFile));
            }
            return false;
        }

        return file_get_contents($targetFile);
    }

    /**
     * @throws Exception
     * @param  $filename
     * @param  $content
     * @return void
     */
    public function store($filename, $content)
    {
        if(!is_dir($this->_targetDirectory))
        {
            if(!$this->_autoCreateDirectory)
            {
                throw new \Exception(sprintf('FileCache directory `%s` doesn\'t exist. Autocreating is disabled.',
                    $this->_targetDirectory));
            }
            else
            {
                if(@mkdir($this->_targetDirectory, 0777, true) === false)
                {
                    throw new \Excepiton(spritnf('Unable to create cache directory `%s`', $this->_targetDirectory));
                }

                $this->_engine->getLogger()->info(sprintf('FileCache directory created `%s`', $this->_targetDirectory));
            }
        }
        if(!is_writable($this->_targetDirectory))
        {
            throw new \Exception(sprintf('FileCache directory `%s` is not writable.', $this->_targetDirectory));
        }

        $targetFile = $this->_targetDirectory . DIRECTORY_SEPARATOR . $filename;

        $written = file_put_contents($targetFile, $content);

        $this->_engine->getLogger()->info(sprintf('Written to FileCache at `%s` %d bytes of data.',
            $targetFile, $written));
    }
}
